#include "data_manager.h"
#include "common.h"
#include "config.h"
#include "FreeRTOS.h"
#include "task.h"

#define DS18B20_ROM_ADDR 256

static int DS18B20SaveData(PT_ROMDataStruct ptROMData);
static int DS18B20GetData(PT_ROMDataStruct ptROMData);
static void DS18B20FreeMalloc(void);

static T_SaveOpr g_tDS18B20DataOpr = {
	.name     = "ds18b20data",
	.SaveData = DS18B20SaveData,
	.GetData  = DS18B20GetData,
	.FreeMalloc = DS18B20FreeMalloc,
};

static PT_SenseDataStruct g_ptSenseMalloc;

static int DS18B20SaveData(PT_ROMDataStruct ptROMData)
{
	uint8_t ucBuffer[300];
	uint8_t i = 0,uclen;
	uint16_t CrcData;
	PT_SenseDataStruct ptTemp;
	
	ucBuffer[0] = ptROMData->Num;
	ucBuffer[1] = ptROMData->SendTime >> 8;
	ucBuffer[2] = ptROMData->SendTime;
	
	ptTemp = ptROMData->SenseDataHead;
	while(ptTemp)
	{
		if(DS18B20_GetFlag == TGF_IO)
		{
			ucBuffer[3 + i * 12] = ptTemp->Addr[0];
			ucBuffer[4 + i * 12] = ptTemp->Addr[1];
			ucBuffer[5 + i * 12] = ptTemp->Addr[2];
			ucBuffer[6 + i * 12] = ptTemp->Addr[3];
			ucBuffer[7 + i * 12] = ptTemp->Addr[4];
			ucBuffer[8 + i * 12] = ptTemp->Addr[5];
			ucBuffer[9 + i * 12] = ptTemp->Addr[6];
			ucBuffer[10 + i * 12] = ptTemp->Addr[7];
			ucBuffer[11 + i * 12] = ptTemp->UpThr >> 8;
			ucBuffer[12 + i * 12] = ptTemp->UpThr;
			ucBuffer[13 + i * 12] = ptTemp->DownThr >> 8;
			ucBuffer[14 + i * 12] = ptTemp->DownThr;
		}
		else
		{
			ucBuffer[3 + i * 6] = ptTemp->Addr[0];
			ucBuffer[4 + i * 6] = ptTemp->Addr[1];
			ucBuffer[5 + i * 6] = ptTemp->UpThr >> 8;
			ucBuffer[6 + i * 6] = ptTemp->UpThr;
			ucBuffer[7 + i * 6] = ptTemp->DownThr >> 8;
			ucBuffer[8 + i * 6] = ptTemp->DownThr;			
		}
		i++;
		if(i >= 20)
		{
			return -1;
		}
		ptTemp = ptTemp->ptNext;
	}
	if(DS18B20_GetFlag == TGF_IO)
	{
		uclen = i * 12 + 3;
	}
	else
	{
		uclen = i * 6 + 3;
	}
	CrcData = MBCrcCheck(ucBuffer,uclen);
	ucBuffer[uclen] = CrcData >> 8;
	ucBuffer[uclen + 1] = CrcData;
	uclen += 2;
	if(ROM_ChangeData(DS18B20_ROM_ADDR, ucBuffer, uclen))
		return 0;
	else
		return -1;
}

static int DS18B20GetData(PT_ROMDataStruct ptROMData)
{
	uint8_t ucBuffer[300];
	uint16_t uslen,i = 0;
	PT_SenseDataStruct pTemp;
	uint8_t *pucTempAddr;
	
	ROM_GetData(DS18B20_ROM_ADDR, ucBuffer, 1);
	if(DS18B20_GetFlag == TGF_IO)
	{
		uslen = ucBuffer[0] * 12 + 5;
	}
	else
	{
		uslen = ucBuffer[0] * 6 + 5;
	}
	if(uslen > 300)
	{
		return -1;
	}
	ROM_GetData(DS18B20_ROM_ADDR, ucBuffer, uslen);
	if(ReceCrcCheck(ucBuffer, uslen))
	{
		ptROMData->Num = ucBuffer[0];
		ptROMData->SendTime = ucBuffer[1] << 8 | ucBuffer[2];
		g_ptSenseMalloc = (PT_SenseDataStruct)pvPortMalloc(sizeof(T_SenseDataStruct) * ptROMData->Num);
		pTemp = g_ptSenseMalloc;
		ptROMData->SenseDataHead = pTemp;
		if(DS18B20_GetFlag == TGF_IO)
		{
			pucTempAddr = (uint8_t *)pvPortMalloc(8 * ptROMData->Num);
		}
		else
		{
			pucTempAddr = (uint8_t *)pvPortMalloc(2 * ptROMData->Num);
		}
		for(i = 0; i < ptROMData->Num; i++)
		{
			if(DS18B20_GetFlag == TGF_IO)
			{
				pucTempAddr[0] = ucBuffer[3 + i * 12];
				pucTempAddr[1] = ucBuffer[4 + i * 12];
				pucTempAddr[2] = ucBuffer[5 + i * 12];
				pucTempAddr[3] = ucBuffer[6 + i * 12];
				pucTempAddr[4] = ucBuffer[7 + i * 12];
				pucTempAddr[5] = ucBuffer[8 + i * 12];
				pucTempAddr[6] = ucBuffer[9 + i * 12];
				pucTempAddr[7] = ucBuffer[10 + i * 12];
				pTemp->Addr = pucTempAddr;
				pTemp->UpThr = ucBuffer[11 + i * 12] << 8 | ucBuffer[12 + i * 12];
				pTemp->DownThr = ucBuffer[13 + i * 12] << 8 | ucBuffer[14 + i * 12];
				pucTempAddr += 8;
			}
			else
			{
				pucTempAddr[0] = ucBuffer[3 + i * 6];
				pucTempAddr[1] = ucBuffer[4 + i * 6];
				pTemp->Addr = pucTempAddr;
				pTemp->UpThr = ucBuffer[5 + i * 6] << 8 | ucBuffer[6 + i * 6];
				pTemp->DownThr = ucBuffer[7 + i * 6] << 8 | ucBuffer[8 + i * 6];
				pucTempAddr += 2;
			}
			pTemp->ptNext = pTemp + 1;
			pTemp = pTemp->ptNext;
		}
		(pTemp - 1)->ptNext = NULL;
		return 0;
	}
	return -1;
}

static void DS18B20FreeMalloc(void)
{
	vPortFree(g_ptSenseMalloc);
}

int DS18B20DataInit(void)
{
	return RegisterSaveOpr(&g_tDS18B20DataOpr);
}
